package edu.pku.sei.autounit.core;

import edu.pku.sei.autounit.reflect.Primitive;
import edu.pku.sei.autounit.reflect.Type;
import edu.pku.sei.autounit.util.Log;
import edu.pku.sei.autounit.util.NameFactory;
import edu.pku.sei.autounit.util.Properties;
import edu.pku.sei.autounit.util.Statements;

public class VariableFactory {
	private VariableGenerator [] generators;
	public VariableFactory(){
		this.generators = Properties.getVariableGenerators();
	}
	
	public Variable getNonNullVariable(Type type,String name,NameFactory nf){
		for(VariableGenerator vg:generators){
			Variable v = vg.generate(type,name,this,nf);
			if(v!=null)
				return v;
		}
		Log.info("there is no suitable factory for the type "+type.getFullName());
		return new DefaultVariable(type, new Statements(), "null");
	}
	
	public Variable getVariableContinue(Type type,String name,NameFactory nf,VariableGenerator e){
		int i=0;
		for(i=0;i<generators.length;i++)
			if(generators[i].equals(e))
				break;
		for(i++;i<generators.length;i++){
			Variable v = generators[i].generate(type,name,this,nf);
			if(v!=null)
				return v;
		}
		Log.info("there is no suitable factory for the type "+type.getFullName());
		return new DefaultVariable(type, new Statements(), "null");
	}
	
	public Variable getVariable(Type type,String name,VariableFactory vf,NameFactory nf){
		if((!(type instanceof Primitive))&&Math.random()<Properties.getNull())
			return new DefaultVariable(type, new Statements(), "null");
		for(VariableGenerator vg:generators){
			Variable v = vg.generate(type,name,vf,nf);
			if(v!=null)
				return v;
		}
		Log.info("there is no suitable factory for the type "+type.getFullName());
		return new DefaultVariable(type, new Statements(), "null");
	}
}
